/**
 * @p.md
 * 
 * 集群系统主类
 * 提供集群系统的统一入口
 */
import { EventEmitter } from 'events';
import { PID } from '../actor/pid';
import { ActorSystem } from '../actor';
import { Remote } from '../remote/remote';
import { ClusterConfig, DefaultClusterConfig, Member, MemberStatus } from './clusterConfig';
import { ClusterProvider, ClusterProviderEvent, ClusterProviderEventType } from './clusterProvider';
import { ClusterIdentity } from './clusterIdentity';
import { IdentityLookup, LookupStatus, LookupResult } from './identityLookup';
import { MemberList, MemberEvent, MemberEventType } from './memberList';
import { LocalProvider } from './providers/localProvider';
import { LocalIdentityLookup } from './providers/localIdentityLookup';
import crypto from 'crypto';

// 前置声明ClusterRouter，避免循环依赖
class ClusterRouter {}

/**
 * 集群事件类型
 */
export enum ClusterEventType {
  /**
   * 集群已初始化
   */
  ClusterInitialized = 'cluster-initialized',
  
  /**
   * 集群已启动
   */
  ClusterStarted = 'cluster-started',
  
  /**
   * 集群已关闭
   */
  ClusterStopped = 'cluster-stopped',
  
  /**
   * 成员已加入
   */
  MemberJoined = 'member-joined',
  
  /**
   * 成员已离开
   */
  MemberLeft = 'member-left',
  
  /**
   * 成员状态变更
   */
  MemberStatusChanged = 'member-status-changed',
  
  /**
   * 领导者已选举
   */
  LeaderElected = 'leader-elected'
}

/**
 * 集群事件接口
 */
export interface ClusterEvent {
  /**
   * 事件类型
   */
  type: ClusterEventType;
  
  /**
   * 相关成员
   */
  member?: Member;
  
  /**
   * 领导者ID
   */
  leaderId?: string;
  
  /**
   * 事件时间戳
   */
  timestamp: number;
  
  /**
   * 附加数据
   */
  data?: any;
}

/**
 * 集群类
 * 管理整个集群的生命周期和通信
 */
export class Cluster extends EventEmitter {
  /**
   * 是否已初始化
   */
  private initialized: boolean = false;
  
  /**
   * 是否已启动
   */
  private running: boolean = false;

  /**
   * 本节点ID
   */
  private nodeId: string;
  
  /**
   * 成员列表
   */
  private memberList: MemberList;
  
  /**
   * 集群提供者
   */
  private provider: ClusterProvider;
  
  /**
   * 身份查找服务
   */
  private identityLookup: IdentityLookup;
  
  /**
   * 集群路由器
   */
  router: ClusterRouter | null = null;

  /**
   * 构造函数
   * 
   * @param actorSystem Actor系统
   * @param remote 远程通信系统
   * @param config 集群配置
   * @param provider 集群提供者
   * @param identityLookup 身份查找服务
   */
  constructor(
    private actorSystem: ActorSystem,
    private remote: Remote,
    private config: ClusterConfig = DefaultClusterConfig,
    provider?: ClusterProvider,
    identityLookup?: IdentityLookup
  ) {
    super();
    
    // 生成节点ID (如果未指定)
    this.nodeId = this.config.nodeAddress || this.generateNodeId();
    
    // 初始化成员列表
    this.memberList = new MemberList();
    this.memberList.setLocalMemberId(this.nodeId);
    
    // 设置集群提供者
    this.provider = provider || this.createDefaultProvider();
    
    // 设置身份查找服务
    this.identityLookup = identityLookup || this.createDefaultIdentityLookup();
    
    // 注册成员列表事件处理
    this.setupMemberListHandlers();
  }

  /**
   * 生成唯一节点ID
   */
  private generateNodeId(): string {
    const { hostname, port } = this.config;
    const randomPart = crypto.randomBytes(4).toString('hex');
    return `${hostname}:${port}-${randomPart}`;
  }

  /**
   * 创建默认集群提供者
   */
  private createDefaultProvider(): ClusterProvider {
    // 使用本地集群提供者作为默认实现
    return new LocalProvider();
  }

  /**
   * 创建默认身份查找服务
   */
  private createDefaultIdentityLookup(): IdentityLookup {
    // 使用本地身份查找服务作为默认实现
    return new LocalIdentityLookup();
  }

  /**
   * 设置成员列表事件处理
   */
  private setupMemberListHandlers(): void {
    // 成员加入事件
    this.memberList.on(MemberEventType.MemberJoined, (memberEvent: MemberEvent) => {
      const clusterEvent: ClusterEvent = {
        type: ClusterEventType.MemberJoined,
        member: memberEvent.member,
        timestamp: memberEvent.timestamp
      };
      this.emit(ClusterEventType.MemberJoined, clusterEvent);
    });

    // 成员离开事件
    this.memberList.on(MemberEventType.MemberLeft, (memberEvent: MemberEvent) => {
      const clusterEvent: ClusterEvent = {
        type: ClusterEventType.MemberLeft,
        member: memberEvent.member,
        timestamp: memberEvent.timestamp
      };
      this.emit(ClusterEventType.MemberLeft, clusterEvent);
    });

    // 成员状态变更事件
    this.memberList.on(MemberEventType.MemberStatusChanged, (memberEvent: MemberEvent) => {
      const clusterEvent: ClusterEvent = {
        type: ClusterEventType.MemberStatusChanged,
        member: memberEvent.member,
        timestamp: memberEvent.timestamp,
        data: { oldStatus: memberEvent.oldStatus }
      };
      this.emit(ClusterEventType.MemberStatusChanged, clusterEvent);
    });
  }

  /**
   * 设置集群提供者事件处理
   */
  private setupProviderHandlers(): void {
    this.provider.registerEventListener((event: ClusterProviderEvent) => {
      switch (event.type) {
        case ClusterProviderEventType.MemberJoined:
          if (event.member) {
            this.memberList.addMember(event.member);
          }
          break;
          
        case ClusterProviderEventType.MemberLeft:
          if (event.member) {
            this.memberList.removeMember(event.member.id);
          }
          break;
          
        case ClusterProviderEventType.MemberAvailable:
          if (event.member) {
            this.memberList.updateMemberStatus(event.member.id, MemberStatus.Alive);
          }
          break;
          
        case ClusterProviderEventType.MemberUnavailable:
          if (event.member) {
            this.memberList.updateMemberStatus(event.member.id, MemberStatus.Unavailable);
          }
          break;
          
        case ClusterProviderEventType.LeaderElected:
          if (event.leaderId) {
            const clusterEvent: ClusterEvent = {
              type: ClusterEventType.LeaderElected,
              leaderId: event.leaderId,
              timestamp: event.timestamp || Date.now()
            };
            this.emit(ClusterEventType.LeaderElected, clusterEvent);
          }
          break;
      }
    });
  }

  /**
   * 初始化集群
   */
  async init(): Promise<void> {
    if (this.initialized) {
      return;
    }

    // 确保远程系统已启动
    if (!this.remote.isStarted()) {
      throw new Error('远程通信系统必须先启动');
    }

    // 初始化集群提供者
    await this.provider.init(this);
    
    // 设置提供者事件处理
    this.setupProviderHandlers();
    
    // 初始化身份查找服务
    await this.identityLookup.init(this);

    this.initialized = true;
    
    // 触发初始化完成事件
    const event: ClusterEvent = {
      type: ClusterEventType.ClusterInitialized,
      timestamp: Date.now()
    };
    this.emit(ClusterEventType.ClusterInitialized, event);
  }

  /**
   * 启动集群
   */
  async start(): Promise<void> {
    if (this.running) {
      return;
    }

    if (!this.initialized) {
      await this.init();
    }

    // 启动集群提供者
    await this.provider.start();
    
    // 注册本节点到集群
    await this.provider.registerMember(this.nodeId);

    this.running = true;
    
    // 触发启动完成事件
    const event: ClusterEvent = {
      type: ClusterEventType.ClusterStarted,
      timestamp: Date.now()
    };
    this.emit(ClusterEventType.ClusterStarted, event);
  }

  /**
   * 关闭集群
   */
  async shutdown(): Promise<void> {
    if (!this.running) {
      return;
    }

    // 取消注册本节点
    await this.provider.unregisterMember();
    
    // 关闭集群提供者
    await this.provider.shutdown();
    
    // 关闭身份查找服务
    await this.identityLookup.shutdown();

    this.running = false;
    this.initialized = false;
    
    // 清空成员列表
    this.memberList.clear();
    
    // 触发关闭完成事件
    const event: ClusterEvent = {
      type: ClusterEventType.ClusterStopped,
      timestamp: Date.now()
    };
    this.emit(ClusterEventType.ClusterStopped, event);
  }

  /**
   * 获取节点ID
   */
  getNodeId(): string {
    return this.nodeId;
  }

  /**
   * 获取配置
   */
  getConfig(): ClusterConfig {
    return this.config;
  }

  /**
   * 获取成员列表
   */
  getMemberList(): MemberList {
    return this.memberList;
  }

  /**
   * 获取集群提供者
   */
  getProvider(): ClusterProvider {
    return this.provider;
  }

  /**
   * 获取身份查找服务
   */
  getIdentityLookup(): IdentityLookup {
    return this.identityLookup;
  }

  /**
   * 获取Actor系统
   */
  getActorSystem(): ActorSystem {
    return this.actorSystem;
  }

  /**
   * 获取远程系统
   */
  getRemote(): Remote {
    return this.remote;
  }

  /**
   * 查找Actor
   * @param kind Actor类型
   * @param identity 身份标识
   * @param timeout 超时时间(毫秒)
   */
  async getAsync(kind: string, identity: string, timeout?: number): Promise<PID | null> {
    console.log(`[Cluster.getAsync] 开始查找: kind=${kind}, identity=${identity}`);
    const clusterIdentity = new ClusterIdentity(kind, identity);
    console.log(`[Cluster.getAsync] 创建ClusterIdentity: ${clusterIdentity.toString()}`);
    
    const result = await this.identityLookup.lookup(clusterIdentity, timeout);
    console.log(`[Cluster.getAsync] 查找结果: status=${result.status}, pid=${result.pid?.toString() || 'null'}`);
    
    if (result.status === LookupStatus.Success) {
      console.log(`[Cluster.getAsync] 查找成功: ${result.pid?.toString()}`);
      return result.pid || null;
    }
    
    if (result.error) {
      console.error(`[Cluster.getAsync] 查找失败: ${result.error}`);
    } else {
      console.error(`[Cluster.getAsync] 查找失败: 未知错误`);
    }
    
    return null;
  }

  /**
   * 检查是否为领导节点
   */
  async isLeader(): Promise<boolean> {
    return this.provider.isLeader();
  }

  /**
   * 获取领导节点
   */
  async getLeader(): Promise<Member | null> {
    return this.provider.getLeader();
  }

  /**
   * 获取所有成员
   */
  async getMembers(): Promise<Member[]> {
    return this.provider.getMembers();
  }

  /**
   * 是否已初始化
   */
  isInitialized(): boolean {
    return this.initialized;
  }

  /**
   * 是否已启动
   */
  isRunning(): boolean {
    return this.running;
  }

  /**
   * 设置路由器
   * @param router 集群路由器
   */
  setRouter(router: ClusterRouter): void {
    this.router = router;
  }

  /**
   * 获取路由器
   */
  getRouter(): ClusterRouter | null {
    return this.router;
  }
} 